package io.sundial.console;

import org.springframework.core.Ordered;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 参数绑定异常解析器
 *
 * @author 杨昌沛 646742615@qq.com
 * 2018/10/8
 */
public class ValidationExceptionHandler implements HandlerExceptionResolver, Ordered {

    @Override
    public int getOrder() {
        return -2;
    }

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        BindingResult result;
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            result = exception.getBindingResult();
        } else if (ex instanceof BindException) {
            BindException exception = (BindException) ex;
            result = exception.getBindingResult();
        } else {
            return null;
        }

        List<ObjectError> errors = result.getAllErrors();
        StringBuilder message = new StringBuilder();
        for (int i = 0; i < errors.size(); i++) {
            ObjectError error = errors.get(i);
            if (message.length() > 0) message.append("\r\n");
            message.append(i + 1).append(". ").append(error.getDefaultMessage());
        }

        ModelAndView mav = new ModelAndView();
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        Map<String, Object> attributes = new LinkedHashMap<>();
        attributes.put("code", 400);
        attributes.put("message", message.toString());
        view.setAttributesMap(attributes);
        mav.setView(view);

        return mav;
    }

}
